home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / wecleman.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  29KB  |  1,096 lines

  1. /***************************************************************************
  2.                         WEC Le Mans 24  &   Hot Chase
  3.  
  4.                           (C)   1986 & 1988 Konami
  5.  
  6.                     driver by    Luca Elia (eliavit@unina.it)
  7.  
  8.  
  9. Note:    if MAME_DEBUG is defined, pressing Z with:
  10.  
  11.         Q        shows background layer
  12.         W        shows foreground layer
  13.         E        shows text layer
  14.         R        shows road layer
  15.         A        shows sprites
  16.         B        toggles the custom gfx browser on/off
  17.  
  18.         Keys can be used togheter!
  19.  
  20.                             [WEC Le Mans 24]
  21.  
  22. [ 2 Scrolling Layers ]
  23.     [Background]
  24.     [Foreground]
  25.         Tile Size:                8x8
  26.  
  27.         Tile Format:
  28.                                         Colour?
  29.                 ---- ba98 7654 3210        Code
  30.  
  31.         Layer Size:                4 Pages -    Page0 Page1
  32.                                             Page2 Page3
  33.                                 each page is 512 x 256 (64 x 32 tiles)
  34.  
  35.         Page Selection Reg.:    108efe    [Bg]
  36.                                 108efc    [Fg]
  37.                                 4 pages to choose from
  38.  
  39.         Scrolling Columns:        1
  40.         Scrolling Columns Reg.:    108f26    [Bg]
  41.                                 108f24    [Fg]
  42.  
  43.         Scrolling Rows:            224 / 8 (Screen-wise scrolling)
  44.         Scrolling Rows Reg.:    108f82/4/6..    [Bg]
  45.                                 108f80/2/4..    [Fg]
  46.  
  47. [ 1 Text Layer ]
  48.         Tile Size:                8x8
  49.  
  50.         Tile Format:
  51.                 fedc ba9- ---- ----        Colour: ba9 fedc
  52.                 ---- ba98 7654 3210        Code
  53.  
  54.         Layer Size:                1 Page: 512 x 256 (64 x 32 tiles)
  55.  
  56.         Scrolling:                -
  57.  
  58. [ 1 Road Layer ]
  59.  
  60. [ 256 Sprites ]
  61.     Zooming Sprites, see below
  62.  
  63.  
  64.  
  65.                                 [Hot Chase]
  66.  
  67. [ 3 Zooming Layers ]
  68.     [Background]
  69.     [Foreground (text)]
  70.     [Road]
  71.  
  72. [ 256 Sprites ]
  73.     Zooming Sprites, see below
  74.  
  75.  
  76. **************************************************************************/
  77.  
  78. #include "vidhrdw/generic.h"
  79. #include "vidhrdw/konamiic.h"
  80.  
  81. /* Variables only used here: */
  82.  
  83. static struct tilemap *bg_tilemap, *fg_tilemap, *txt_tilemap;
  84. static struct sprite_list *sprite_list;
  85.  
  86.  
  87. /* Variables that driver has acces to: */
  88.  
  89. unsigned char *wecleman_pageram, *wecleman_txtram, *wecleman_roadram, *wecleman_unknown;
  90. size_t wecleman_roadram_size;
  91. int wecleman_bgpage[4], wecleman_fgpage[4], *wecleman_gfx_bank;
  92.  
  93.  
  94.  
  95. /* Variables defined in driver: */
  96.  
  97. extern int wecleman_selected_ip, wecleman_irqctrl;
  98.  
  99.  
  100.  
  101. /***************************************************************************
  102.                             Common routines
  103. ***************************************************************************/
  104.  
  105. /* Useful defines - for debug */
  106. #define KEY(_k_,_action_) \
  107.     if (keyboard_pressed(KEYCODE_##_k_))    { while (keyboard_pressed(KEYCODE_##_k_)); _action_ }
  108. #define KEY_SHIFT(_k_,_action_) \
  109.     if ( (keyboard_pressed(KEYCODE_LSHIFT)||keyboard_pressed(KEYCODE_RSHIFT)) && \
  110.           keyboard_pressed(KEYCODE_##_k_) )    { while (keyboard_pressed(KEYCODE_##_k_)); _action_ }
  111. #define KEY_FAST(_k_,_action_) \
  112.     if (keyboard_pressed(KEYCODE_##_k_))    { _action_ }
  113.  
  114.  
  115. /* WEC Le Mans 24 and Hot Chase share the same sprite hardware */
  116. #define NUM_SPRITES 256
  117.  
  118.  
  119. WRITE_HANDLER( paletteram_SBGRBBBBGGGGRRRR_word_w )
  120. {
  121.     /*    byte 0        byte 1        */
  122.     /*    SBGR BBBB     GGGG RRRR    */
  123.     /*    S000 4321     4321 4321    */
  124.     /*  S = Shade                */
  125.  
  126.     int oldword = READ_WORD (&paletteram[offset]);
  127.     int newword = COMBINE_WORD (oldword, data);
  128.  
  129.     int r = ((newword << 1) & 0x1E ) | ((newword >> 12) & 0x01);
  130.     int g = ((newword >> 3) & 0x1E ) | ((newword >> 13) & 0x01);
  131.     int b = ((newword >> 7) & 0x1E ) | ((newword >> 14) & 0x01);
  132.  
  133.     /* This effect can be turned on/off actually ... */
  134.     if (newword & 0x8000)    { r /= 2;     g /= 2;     b /= 2; }
  135.  
  136.     palette_change_color( offset/2,     (r * 0xFF) / 0x1F,
  137.                                      (g * 0xFF) / 0x1F,
  138.                                      (b * 0xFF) / 0x1F     );
  139.  
  140.     WRITE_WORD (&paletteram[offset], newword);
  141. }
  142.  
  143.  
  144.  
  145.  
  146. /***************************************************************************
  147.  
  148.                       Callbacks for the TileMap code
  149.  
  150. ***************************************************************************/
  151.  
  152.  
  153.  
  154. /***************************************************************************
  155.                                 WEC Le Mans 24
  156. ***************************************************************************/
  157.  
  158. #define PAGE_NX          (0x40)
  159. #define PAGE_NY          (0x20)
  160. #define PAGE_GFX        (0)
  161. #define TILEMAP_DIMY    (PAGE_NY * 2 * 8)
  162.  
  163. /*------------------------------------------------------------------------
  164.                 [ Frontmost (text) layer + video registers ]
  165. ------------------------------------------------------------------------*/
  166.  
  167.  
  168.  
  169. void wecleman_get_txt_tile_info( int tile_index )
  170. {
  171.     int code         =    READ_WORD(&wecleman_txtram[tile_index*2]);
  172.     SET_TILE_INFO(PAGE_GFX, code & 0xfff, (code >> 12) + ((code >> 5) & 0x70) );
  173. }
  174.  
  175.  
  176.  
  177.  
  178. READ_HANDLER( wecleman_txtram_r )
  179. {
  180.     return READ_WORD(&wecleman_txtram[offset]);
  181. }
  182.  
  183.  
  184.  
  185.  
  186. WRITE_HANDLER( wecleman_txtram_w )
  187. {
  188.     int old_data = READ_WORD(&wecleman_txtram[offset]);
  189.     int new_data = COMBINE_WORD(old_data,data);
  190.  
  191.     if ( old_data != new_data )
  192.     {
  193.         WRITE_WORD(&wecleman_txtram[offset], new_data);
  194.  
  195.         if (offset >= 0xE00 )    /* Video registers */
  196.         {
  197.             /* pages selector for the background */
  198.             if (offset == 0xEFE)
  199.             {
  200.                 wecleman_bgpage[0] = (new_data >> 0x4) & 3;
  201.                 wecleman_bgpage[1] = (new_data >> 0x0) & 3;
  202.                 wecleman_bgpage[2] = (new_data >> 0xc) & 3;
  203.                 wecleman_bgpage[3] = (new_data >> 0x8) & 3;
  204.                 tilemap_mark_all_tiles_dirty(bg_tilemap);
  205.             }
  206.  
  207.             /* pages selector for the foreground */
  208.             if (offset == 0xEFC)
  209.             {
  210.                 wecleman_fgpage[0] = (new_data >> 0x4) & 3;
  211.                 wecleman_fgpage[1] = (new_data >> 0x0) & 3;
  212.                 wecleman_fgpage[2] = (new_data >> 0xc) & 3;
  213.                 wecleman_fgpage[3] = (new_data >> 0x8) & 3;
  214.                 tilemap_mark_all_tiles_dirty(fg_tilemap);
  215.             }
  216.  
  217.             /* Parallactic horizontal scroll registers follow */
  218.  
  219.         }
  220.         else
  221.             tilemap_mark_tile_dirty(txt_tilemap, offset / 2);
  222.     }
  223. }
  224.  
  225.  
  226.  
  227.  
  228. /*------------------------------------------------------------------------
  229.                             [ Background ]
  230. ------------------------------------------------------------------------*/
  231.  
  232.  
  233.  
  234. void wecleman_get_bg_tile_info( int tile_index )
  235. {
  236.     int page = wecleman_bgpage[(tile_index%(PAGE_NX*2))/PAGE_NX+2*(tile_index/(PAGE_NX*PAGE_NY*2))];
  237.     int code = READ_WORD(&wecleman_pageram[( (tile_index%PAGE_NX) + PAGE_NX*((tile_index/(PAGE_NX*2))%PAGE_NY) + page*PAGE_NX*PAGE_NY ) * 2]);
  238.     SET_TILE_INFO(PAGE_GFX, code & 0xfff, (code >> 12) + ((code >> 5) & 0x70) );
  239. }
  240.  
  241.  
  242.  
  243. /*------------------------------------------------------------------------
  244.                             [ Foreground ]
  245. ------------------------------------------------------------------------*/
  246.  
  247.  
  248.  
  249. void wecleman_get_fg_tile_info( int tile_index )
  250. {
  251.     int page = wecleman_fgpage[(tile_index%(PAGE_NX*2))/PAGE_NX+2*(tile_index/(PAGE_NX*PAGE_NY*2))];
  252.     int code = READ_WORD(&wecleman_pageram[( (tile_index%PAGE_NX) + PAGE_NX*((tile_index/(PAGE_NX*2))%PAGE_NY) + page*PAGE_NX*PAGE_NY ) * 2]);
  253.     SET_TILE_INFO(PAGE_GFX, code & 0xfff, (code >> 12) + ((code >> 5) & 0x70) );
  254. }
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261. /*------------------------------------------------------------------------
  262.                     [ Pages (Background & Foreground) ]
  263. ------------------------------------------------------------------------*/
  264.  
  265.  
  266.  
  267. /* Pages that compose both the background and the foreground */
  268. READ_HANDLER( wecleman_pageram_r )
  269. {
  270.     return READ_WORD(&wecleman_pageram[offset]);
  271. }
  272.  
  273.  
  274. WRITE_HANDLER( wecleman_pageram_w )
  275. {
  276.     int old_data = READ_WORD(&wecleman_pageram[offset]);
  277.     int new_data = COMBINE_WORD(old_data,data);
  278.  
  279.     if ( old_data != new_data )
  280.     {
  281.         int page,col,row;
  282.  
  283.         WRITE_WORD(&wecleman_pageram[offset], new_data);
  284.  
  285.         page    =    ( offset / 2 ) / (PAGE_NX * PAGE_NY);
  286.  
  287.         col        =    ( offset / 2 )           % PAGE_NX;
  288.         row        =    ( offset / 2 / PAGE_NX ) % PAGE_NY;
  289.  
  290.         /* background */
  291.         if (wecleman_bgpage[0] == page)    tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*0)*PAGE_NX*2 );
  292.         if (wecleman_bgpage[1] == page)    tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*0)*PAGE_NX*2 );
  293.         if (wecleman_bgpage[2] == page)    tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*1)*PAGE_NX*2 );
  294.         if (wecleman_bgpage[3] == page)    tilemap_mark_tile_dirty(bg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*1)*PAGE_NX*2 );
  295.  
  296.         /* foreground */
  297.         if (wecleman_fgpage[0] == page)    tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*0)*PAGE_NX*2 );
  298.         if (wecleman_fgpage[1] == page)    tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*0)*PAGE_NX*2 );
  299.         if (wecleman_fgpage[2] == page)    tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*0) + (row+PAGE_NY*1)*PAGE_NX*2 );
  300.         if (wecleman_fgpage[3] == page)    tilemap_mark_tile_dirty(fg_tilemap, (col+PAGE_NX*1) + (row+PAGE_NY*1)*PAGE_NX*2 );
  301.     }
  302. }
  303.  
  304.  
  305.  
  306. /*------------------------------------------------------------------------
  307.                         [ Video Hardware Start ]
  308. ------------------------------------------------------------------------*/
  309.  
  310. int wecleman_vh_start(void)
  311. {
  312.  
  313. /*
  314.  Sprite banking - each bank is 0x20000 bytes (we support 0x40 bank codes)
  315.  This game has ROMs for 16 banks
  316. */
  317.  
  318.     static int bank[0x40] = {    0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
  319.                                 8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,
  320.                                 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
  321.                                 8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15    };
  322.  
  323.     wecleman_gfx_bank = bank;
  324.  
  325.  
  326.     bg_tilemap = tilemap_create(wecleman_get_bg_tile_info,
  327.                                 tilemap_scan_rows,
  328.                                 TILEMAP_TRANSPARENT,    /* We draw part of the road below */
  329.                                 8,8,
  330.                                 PAGE_NX * 2, PAGE_NY * 2 );
  331.  
  332.     fg_tilemap = tilemap_create(wecleman_get_fg_tile_info,
  333.                                 tilemap_scan_rows,
  334.                                 TILEMAP_TRANSPARENT,
  335.                                 8,8,
  336.                                 PAGE_NX * 2, PAGE_NY * 2);
  337.  
  338.     txt_tilemap = tilemap_create(wecleman_get_txt_tile_info,
  339.                                  tilemap_scan_rows,
  340.                                  TILEMAP_TRANSPARENT,
  341.                                  8,8,
  342.                                  PAGE_NX * 1, PAGE_NY * 1);
  343.  
  344.  
  345.     sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
  346.  
  347.  
  348.     if (bg_tilemap && fg_tilemap && txt_tilemap && sprite_list)
  349.     {
  350.         tilemap_set_scroll_rows(bg_tilemap, TILEMAP_DIMY);    /* Screen-wise scrolling */
  351.         tilemap_set_scroll_cols(bg_tilemap, 1);
  352.         bg_tilemap->transparent_pen = 0;
  353.  
  354.         tilemap_set_scroll_rows(fg_tilemap, TILEMAP_DIMY);    /* Screen-wise scrolling */
  355.         tilemap_set_scroll_cols(fg_tilemap, 1);
  356.         fg_tilemap->transparent_pen = 0;
  357.  
  358.         tilemap_set_scroll_rows(txt_tilemap, 1);
  359.         tilemap_set_scroll_cols(txt_tilemap, 1);
  360.         txt_tilemap->transparent_pen = 0;
  361.         tilemap_set_scrollx(txt_tilemap,0, 512-320-16 );    /* fixed scrolling? */
  362.         tilemap_set_scrolly(txt_tilemap,0, 0 );
  363.  
  364.         sprite_list->max_priority = 0;
  365.         sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
  366.  
  367.         return 0;
  368.     }
  369.     else return 1;
  370. }
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384. /***************************************************************************
  385.                                 Hot Chase
  386. ***************************************************************************/
  387.  
  388.  
  389. /***************************************************************************
  390.  
  391.   Callbacks for the K051316
  392.  
  393. ***************************************************************************/
  394.  
  395. #define ZOOMROM0_MEM_REGION REGION_GFX2
  396. #define ZOOMROM1_MEM_REGION REGION_GFX3
  397.  
  398. static void zoom_callback_0(int *code,int *color)
  399. {
  400.     *code |= (*color & 0x03) << 8;
  401.     *color = (*color & 0xfc) >> 2;
  402. }
  403.  
  404. static void zoom_callback_1(int *code,int *color)
  405. {
  406.     *code |= (*color & 0x01) << 8;
  407.     *color = ((*color & 0x3f) << 1) | ((*code & 0x80) >> 7);
  408. }
  409.  
  410.  
  411.  
  412. /*------------------------------------------------------------------------
  413.                         [ Video Hardware Start ]
  414. ------------------------------------------------------------------------*/
  415.  
  416. /* for the zoomed layers we support: road and fg */
  417. static struct osd_bitmap *temp_bitmap, *temp_bitmap2;
  418.  
  419. int hotchase_vh_start(void)
  420. {
  421. /*
  422.  Sprite banking - each bank is 0x20000 bytes (we support 0x40 bank codes)
  423.  This game has ROMs for 0x30 banks
  424. */
  425.     static int bank[0x40] = {    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  426.                                 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  427.                                 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  428.                                 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15    };
  429.     wecleman_gfx_bank = bank;
  430.  
  431.  
  432.     if (K051316_vh_start_0(ZOOMROM0_MEM_REGION,4,zoom_callback_0))
  433.         return 1;
  434.  
  435.     if (K051316_vh_start_1(ZOOMROM1_MEM_REGION,4,zoom_callback_1))
  436.     {
  437.         K051316_vh_stop_0();
  438.         return 1;
  439.     }
  440.  
  441.     temp_bitmap  = osd_create_bitmap(512,512);
  442.     temp_bitmap2 = osd_create_bitmap(512,256);
  443.  
  444.     sprite_list = sprite_list_create( NUM_SPRITES, SPRITE_LIST_BACK_TO_FRONT | SPRITE_LIST_RAW_DATA );
  445.  
  446.     if (temp_bitmap && temp_bitmap2 && sprite_list)
  447.     {
  448.         K051316_wraparound_enable(0,1);
  449. //        K051316_wraparound_enable(1,1);
  450.         K051316_set_offset(0,-96,-16);
  451.         K051316_set_offset(1,-96,-16);
  452.  
  453.         sprite_list->max_priority = 0;
  454.         sprite_list->sprite_type = SPRITE_TYPE_ZOOM;
  455.  
  456.         return 0;
  457.     }
  458.     else return 1;
  459. }
  460.  
  461. void hotchase_vh_stop(void)
  462. {
  463.     if (temp_bitmap)    osd_free_bitmap(temp_bitmap);
  464.     if (temp_bitmap2)    osd_free_bitmap(temp_bitmap2);
  465.     K051316_vh_stop_0();
  466.     K051316_vh_stop_1();
  467. }
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475. /***************************************************************************
  476.  
  477.                                 Road Drawing
  478.  
  479. ***************************************************************************/
  480.  
  481.  
  482. /***************************************************************************
  483.                                 WEC Le Mans 24
  484. ***************************************************************************/
  485.  
  486. #define ROAD_COLOR(x)    (0x00 + ((x)&0xff))
  487.  
  488. void wecleman_mark_road_colors(void)
  489. {
  490.     int y                    =    Machine->drv->visible_area.min_y;
  491.     int ymax                =    Machine->drv->visible_area.max_y;
  492.     int color_codes_start    =    Machine->drv->gfxdecodeinfo[1].color_codes_start;
  493.  
  494.     for (; y <= ymax; y++)
  495.     {
  496.         int color = ROAD_COLOR( READ_WORD(&wecleman_roadram[0x400 + y * 2]) );
  497.         memset(&palette_used_colors[color_codes_start + color*8],PALETTE_COLOR_USED,8);    // no transparency
  498.     }
  499. }
  500.  
  501.  
  502. /*
  503.  
  504.     This layer is composed of horizontal lines gfx elements
  505.     There are 256 lines in ROM, each is 512 pixels wide
  506.  
  507.     Offset:        Elements:    Data:
  508.  
  509.     0000-01ff    100 Words    Code
  510.  
  511.         fedcba98--------    Priority?
  512.         --------76543210    Line Number
  513.  
  514.     0200-03ff    100 Words    Horizontal Scroll
  515.     0400-05ff    100 Words    Color
  516.     0600-07ff    100 Words    ??
  517.  
  518.     We draw each line using a bunch of 64x1 tiles
  519.  
  520. */
  521.  
  522. void wecleman_draw_road(struct osd_bitmap *bitmap,int priority)
  523. {
  524.     struct rectangle rect = Machine->drv->visible_area;
  525.     int curr_code, sx,sy;
  526.  
  527. /* Referred to what's in the ROMs */
  528. #define XSIZE 512
  529. #define YSIZE 256
  530.  
  531.     /* Let's draw from the top to the bottom of the visible screen */
  532.     for (sy = rect.min_y ; sy <= rect.max_y ; sy ++)
  533.     {
  534.         int code        =    READ_WORD(&wecleman_roadram[(YSIZE*0+sy)*2]);
  535.         int scrollx     =    READ_WORD(&wecleman_roadram[(YSIZE*1+sy)*2]) + 24;    // fudge factor :)
  536.         int attr        =    READ_WORD(&wecleman_roadram[(YSIZE*2+sy)*2]);
  537.  
  538.         /* high byte is a priority information? */
  539.         if ((code>>8) != priority)    continue;
  540.  
  541.         /* line number converted to tile number (each tile is 64x1) */
  542.         code        =    (code % YSIZE) * (XSIZE/64);
  543.  
  544.         /* Scroll value applies to a "picture" twice as wide as the gfx
  545.            in ROM: left half is color 15, right half is the gfx */
  546.         scrollx %= XSIZE * 2;
  547.  
  548.         if (scrollx >= XSIZE)    {curr_code = code+(scrollx-XSIZE)/64;    code = 0;}
  549.         else                    {curr_code = 0   + scrollx/64;}
  550.  
  551.         for (sx = -(scrollx % 64) ; sx <= rect.max_x ; sx += 64)
  552.         {
  553.             drawgfx(bitmap,Machine->gfx[1],
  554.                 curr_code++,
  555.                 ROAD_COLOR(attr),
  556.                 0,0,
  557.                 sx,sy,
  558.                 &rect,
  559.                 TRANSPARENCY_NONE,0);
  560.  
  561.             if ( (curr_code % (XSIZE/64)) == 0)    curr_code = code;
  562.         }
  563.     }
  564.  
  565. #undef XSIZE
  566. #undef YSIZE
  567. }
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574. /***************************************************************************
  575.                             Hot Chase
  576. ***************************************************************************/
  577.  
  578.  
  579.  
  580.  
  581. void hotchase_mark_road_colors(void)
  582. {
  583.     int y                    =    Machine->drv->visible_area.min_y;
  584.     int ymax                =    Machine->drv->visible_area.max_y;
  585.     int color_codes_start    =    Machine->drv->gfxdecodeinfo[0].color_codes_start;
  586.  
  587.     for (; y <= ymax; y++)
  588.     {
  589.         int color = (READ_WORD(&wecleman_roadram[y * 4]) >> 4 ) & 0xf;
  590.         palette_used_colors[color_codes_start + color*16 + 0] = PALETTE_COLOR_TRANSPARENT;    // pen 0 transparent
  591.         memset(&palette_used_colors[color_codes_start + color*16 + 1],PALETTE_COLOR_USED,16-1);
  592.     }
  593.  
  594. }
  595.  
  596.  
  597.  
  598.  
  599. /*
  600.     This layer is composed of horizontal lines gfx elements
  601.     There are 512 lines in ROM, each is 512 pixels wide
  602.  
  603.     Offset:        Elements:    Data:
  604.  
  605.     0000-03ff    00-FF        Code (4 bytes)
  606.  
  607.     Code:
  608.  
  609.         00.w
  610.                 fedc ba98 ---- ----        Unused?
  611.                 ---- ---- 7654 ----        color
  612.                 ---- ---- ---- 3210        scroll x
  613.  
  614.         02.w    fedc ba-- ---- ----        scroll x
  615.                 ---- --9- ---- ----        ?
  616.                 ---- ---8 7654 3210        code
  617.  
  618.     We draw each line using a bunch of 64x1 tiles
  619.  
  620. */
  621.  
  622. void hotchase_draw_road(struct osd_bitmap *bitmap,int priority, struct rectangle *clip)
  623. {
  624. struct rectangle rect = *clip;
  625. int sy;
  626.  
  627.  
  628. /* Referred to what's in the ROMs */
  629. #define XSIZE 512
  630. #define YSIZE 512
  631.  
  632.  
  633.     /* Let's draw from the top to the bottom of the visible screen */
  634.     for (sy = rect.min_y ; sy <= rect.max_y ; sy ++)
  635.     {
  636.         int curr_code,sx;
  637.         int code    =      READ_WORD(&wecleman_roadram[0x0000+sy*4+2]) +
  638.                         ( READ_WORD(&wecleman_roadram[0x0000+sy*4+0]) << 16 );
  639.         int color    =    (( code & 0x00f00000 ) >> 20 ) + 0x70;
  640.         int scrollx =     ( code & 0x000ffc00 ) >> 10;
  641.         code        =     ( code & 0x000003ff ) >>  0;
  642.  
  643.         /* convert line number in gfx element number: */
  644.         /* code is the tile code of the start of this line */
  645.         code    = ( code % YSIZE ) * ( XSIZE / 64 );
  646.  
  647. //        if (scrollx < 0) scrollx += XSIZE * 2 ;
  648.         scrollx %= XSIZE * 2;
  649.  
  650.         if (scrollx < XSIZE)    {curr_code = code + scrollx/64;    code = 0;}
  651.         else                    {curr_code = 0    + scrollx/64;}
  652.  
  653.         for (sx = -(scrollx % 64) ; sx <= rect.max_x ; sx += 64)
  654.         {
  655.             drawgfx(bitmap,Machine->gfx[0],
  656.                 curr_code++,
  657.                 color,
  658.                 0,0,
  659.                 sx,sy,
  660.                 &rect,
  661.                 TRANSPARENCY_PEN,0);
  662.  
  663.             /* Maybe after the end of a line of gfx we shouldn't
  664.                wrap around, but pad with a value */
  665.             if ((curr_code % (XSIZE/64)) == 0)    curr_code = code;
  666.         }
  667.     }
  668.  
  669. #undef XSIZE
  670. #undef YSIZE
  671. }
  672.  
  673.  
  674.  
  675.  
  676. /***************************************************************************
  677.  
  678.                             Sprites Drawing
  679.  
  680. ***************************************************************************/
  681.  
  682. /* Hot Chase: shadow of trees is pen 0x0a - Should it be black like it is now */
  683.  
  684. static void mark_sprites_colors(void)
  685. {
  686.     int offs;
  687.  
  688.     for (offs = 0; offs < (NUM_SPRITES * 0x10); offs += 0x10)
  689.     {
  690.         int dest_y, dest_h, color;
  691.  
  692.         dest_y = READ_WORD(&spriteram[offs + 0x00]);
  693.         if (dest_y == 0xFFFF)    break;
  694.  
  695.         dest_h = (dest_y >> 8) - (dest_y & 0x00FF);
  696.         if (dest_h < 1) continue;
  697.  
  698.         color = (READ_WORD(&spriteram[offs + 0x04]) >> 8) & 0x7f;
  699.         memset(&palette_used_colors[color*16 + 1], PALETTE_COLOR_USED, 16 - 2 );
  700.  
  701.         // pens 0 & 15 are transparent
  702.         palette_used_colors[color*16 + 0] = palette_used_colors[color*16 + 15] = PALETTE_COLOR_TRANSPARENT;
  703.     }
  704. }
  705.  
  706.  
  707.  
  708.  
  709. /*
  710.  
  711.     Sprites: 256 entries, 16 bytes each, first ten bytes used (and tested)
  712.  
  713.     Offset    Bits                    Meaning
  714.  
  715.     00.w    fedc ba98 ---- ----        Screen Y start
  716.             ---- ---- 7654 3210        Screen Y stop
  717.  
  718.     02.w    fedc ba-- ---- ----        High bits of sprite "address"
  719.             ---- --9- ---- ----        Flip Y ?
  720.             ---- ---8 7654 3210        Screen X start
  721.  
  722.     04.w    fedc ba98 ---- ----        Color
  723.             ---- ---- 7654 3210        Source Width / 8
  724.  
  725.     06.w    f--- ---- ---- ----        Flip X
  726.             -edc ba98 7654 3210        Low bits of sprite "address"
  727.  
  728.     08.w    --dc ba98 ---- ----        Y? Shrink Factor
  729.             ---- ---- --54 3210        X? Shrink Factor
  730.  
  731. Sprite "address" is the index of the pixel the hardware has to start
  732. fetching data from, divided by 8. Only on screen height and source data
  733. width are provided, along with two shrinking factors. So on screen width
  734. and source height are calculated by the hardware using the shrink factors.
  735. The factors are in the range 0 (no shrinking) - 3F (half size).
  736.  
  737. */
  738.  
  739. static void get_sprite_info(void)
  740. {
  741.     const unsigned short *base_pal    = Machine->remapped_colortable;
  742.     const unsigned char  *base_gfx    = memory_region(REGION_GFX1);
  743.  
  744.     const int gfx_max = memory_region_length(REGION_GFX1);
  745.  
  746.     unsigned char *source        =    spriteram;
  747.     struct sprite *sprite        =    sprite_list->sprite;
  748.     const struct sprite *finish    =    sprite + NUM_SPRITES;
  749.  
  750.     int visibility = SPRITE_VISIBLE;
  751.  
  752.  
  753. #define SHRINK_FACTOR(x) \
  754.     (1.0 - ( ( (x) & 0x3F ) / 63.0) * 0.5)
  755.  
  756.     for (; sprite < finish; sprite++,source+=0x10)
  757.     {
  758.         int code, gfx, zoom;
  759.  
  760.         sprite->priority = 0;
  761.  
  762.         sprite->y    = READ_WORD(&source[0x00]);
  763.         if (sprite->y == 0xFFFF)    { visibility = 0; }
  764.  
  765.         sprite->flags = visibility;
  766.         if (visibility==0) continue;
  767.  
  768.         sprite->total_height = (sprite->y >> 8) - (sprite->y & 0xFF);
  769.         if (sprite->total_height < 1) {sprite->flags = 0;    continue;}
  770.  
  771.         sprite->x             =    READ_WORD(&source[0x02]);
  772.         sprite->tile_width    =    READ_WORD(&source[0x04]);
  773.         code                =    READ_WORD(&source[0x06]);
  774.         zoom                =    READ_WORD(&source[0x08]);
  775.  
  776.         gfx    = (wecleman_gfx_bank[(sprite->x >> 10) & 0x3f] << 15) +  (code & 0x7fff);
  777.         sprite->pal_data = base_pal + ( (sprite->tile_width >> 4) & 0x7f0 );    // 16 colors = 16 shorts
  778.  
  779.         if (code & 0x8000)
  780.         {    sprite->flags |= SPRITE_FLIPX;    gfx += 1 - (sprite->tile_width & 0xFF);    };
  781.  
  782.         if (sprite->x & 0x0200)        /* ?flip y? */
  783.         {    sprite->flags |= SPRITE_FLIPY; }
  784.  
  785.         gfx *= 8;
  786.  
  787.         sprite->pen_data = base_gfx + gfx;
  788.  
  789.         sprite->tile_width    = (sprite->tile_width & 0xFF) * 8;
  790.         if (sprite->tile_width < 1) {sprite->flags = 0;    continue;}
  791.  
  792.         sprite->tile_height = sprite->total_height * ( 1.0 / SHRINK_FACTOR(zoom>>8) );
  793.         sprite->x   = (sprite->x & 0x1ff) - 0xc0;
  794.         sprite->y   = (sprite->y & 0xff);
  795.         sprite->total_width = sprite->tile_width * SHRINK_FACTOR(zoom & 0xFF);
  796.  
  797.         sprite->line_offset = sprite->tile_width;
  798.  
  799.         /* Bound checking */
  800.         if ((gfx + sprite->tile_width * sprite->tile_height - 1) >= gfx_max )
  801.             {sprite->flags = 0;    continue;}
  802.     }
  803. }
  804.  
  805.  
  806.  
  807. /***************************************************************************
  808.  
  809.                             Browse the graphics
  810.  
  811. ***************************************************************************/
  812.  
  813. /*
  814.     Browse the sprites
  815.  
  816.     Use:
  817.     * LEFT, RIGHT, UP, DOWN and PGUP/PGDN to move around
  818.     * SHIFT + PGUP/PGDN to move around faster
  819.     * SHIFT + LEFT/RIGHT to change the width of the graphics
  820.     * SHIFT + RCTRL to go back to the start of the gfx
  821.  
  822. */
  823. void browser(struct osd_bitmap *bitmap)
  824. {
  825.     const unsigned short *base_pal    =    Machine->gfx[0]->colortable + 0;
  826.     const unsigned char  *base_gfx    =    memory_region(REGION_GFX1);
  827.  
  828.     const int gfx_max                =    memory_region_length(REGION_GFX1);
  829.  
  830.     struct sprite *sprite            =    sprite_list->sprite;
  831.     const struct sprite *finish        =    sprite + NUM_SPRITES;
  832.  
  833.     static int w = 32, gfx;
  834.     char buf[80];
  835.  
  836.     for ( ; sprite < finish ; sprite++)    sprite->flags = 0;
  837.  
  838.     sprite = sprite_list->sprite;
  839.  
  840.     sprite->flags = SPRITE_VISIBLE;
  841.     sprite->x = 0;
  842.     sprite->y = 0;
  843.     sprite->tile_height = sprite->total_height = 224;
  844.     sprite->pal_data = base_pal;
  845.  
  846.     KEY_FAST(LEFT,    gfx-=8;)
  847.     KEY_FAST(RIGHT,    gfx+=8;)
  848.     KEY_FAST(UP,    gfx-=w;)
  849.     KEY_FAST(DOWN,    gfx+=w;)
  850.  
  851.     KEY_SHIFT(PGDN,    gfx -= 0x100000;)
  852.     KEY_SHIFT(PGUP,    gfx += 0x100000;)
  853.  
  854.     KEY(PGDN,gfx+=w*sprite->tile_height;)
  855.     KEY(PGUP,gfx-=w*sprite->tile_height;)
  856.  
  857.     KEY_SHIFT(RCONTROL,    gfx = 0;)
  858.  
  859.     gfx %= gfx_max;
  860.     if (gfx < 0)    gfx += gfx_max;
  861.  
  862.     KEY_SHIFT(LEFT,        w-=8;)
  863.     KEY_SHIFT(RIGHT,    w+=8;)
  864.     w &= 0x1ff;
  865.  
  866.     sprite->pen_data = base_gfx + gfx;
  867.     sprite->tile_width = sprite->total_width = sprite->line_offset = w;
  868.  
  869.     /* Bound checking */
  870.     if ((gfx + sprite->tile_width * sprite->tile_height - 1) >= gfx_max )
  871.         sprite->flags = 0;
  872.  
  873.     sprite_draw( sprite_list, 0 );
  874.  
  875.     sprintf(buf,"W:%02X GFX/8: %X",w,gfx / 8);
  876.     usrintf_showmessage(buf);
  877. }
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890. /***************************************************************************
  891.  
  892.                             Screen Drawing
  893.  
  894. ***************************************************************************/
  895.  
  896. #define WECLEMAN_TVKILL \
  897.     if ((wecleman_irqctrl & 0x40)==0) layers_ctrl = 0;    // TV-KILL
  898.  
  899. #define WECLEMAN_LAMPS \
  900.     osd_led_w(0,(wecleman_selected_ip >> 2)& 1);         // Start lamp
  901.  
  902.  
  903.  
  904. /* You can activate each single layer of gfx */
  905. #define WECLEMAN_LAYERSCTRL \
  906. { \
  907.     static int browse = 0; \
  908.     KEY(B, browse ^= 1;) \
  909.     if (browse) \
  910.     { \
  911.         osd_clearbitmap(Machine->scrbitmap); \
  912.         browser(bitmap); \
  913.         return; \
  914.     } \
  915.     if (keyboard_pressed(KEYCODE_Z)) \
  916.     { \
  917.     int msk = 0; \
  918.      \
  919.         if (keyboard_pressed(KEYCODE_Q))    { msk |= 0xffe1;} \
  920.         if (keyboard_pressed(KEYCODE_W))    { msk |= 0xffe2;} \
  921.         if (keyboard_pressed(KEYCODE_E))    { msk |= 0xffe4;} \
  922.         if (keyboard_pressed(KEYCODE_A))    { msk |= 0xffe8;} \
  923.         if (keyboard_pressed(KEYCODE_R))    { msk |= 0xfff0;} \
  924.         if (msk != 0) layers_ctrl &= msk; \
  925.     } \
  926. }
  927.  
  928.  
  929. /***************************************************************************
  930.                             WEC Le Mans 24
  931. ***************************************************************************/
  932.  
  933. void wecleman_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  934. {
  935.     int i, layers_ctrl = 0xFFFF;
  936.  
  937.  
  938.     WECLEMAN_LAMPS
  939.  
  940.     WECLEMAN_TVKILL
  941.  
  942. #ifdef MAME_DEBUG
  943.     WECLEMAN_LAYERSCTRL
  944. #endif
  945.  
  946. {
  947. /* Set the scroll values for the scrolling layers */
  948.  
  949.     /* y values */
  950.     int bg_y = READ_WORD(&wecleman_txtram[0x0F24+2]) & (TILEMAP_DIMY - 1);
  951.     int fg_y = READ_WORD(&wecleman_txtram[0x0F24+0]) & (TILEMAP_DIMY - 1);
  952.  
  953.     tilemap_set_scrolly(bg_tilemap, 0, bg_y );
  954.     tilemap_set_scrolly(fg_tilemap, 0, fg_y );
  955.  
  956.     /* x values */
  957.     for ( i = 0 ; i < 28; i++ )
  958.     {
  959.         int j;
  960.         int bg_x = 0xB0 + READ_WORD(&wecleman_txtram[0xF80+i*4+2]);
  961.         int fg_x = 0xB0 + READ_WORD(&wecleman_txtram[0xF80+i*4+0]);
  962.  
  963.         for ( j = 0 ; j < 8; j++ )
  964.         {
  965.             tilemap_set_scrollx(bg_tilemap, (bg_y + i*8 + j) & (TILEMAP_DIMY - 1), bg_x );
  966.             tilemap_set_scrollx(fg_tilemap, (fg_y + i*8 + j) & (TILEMAP_DIMY - 1), fg_x );
  967.         }
  968.     }
  969. }
  970.  
  971.  
  972.     tilemap_update(ALL_TILEMAPS);
  973.     get_sprite_info();
  974.  
  975.     palette_init_used_colors();
  976.  
  977.     wecleman_mark_road_colors();
  978.     mark_sprites_colors();
  979.  
  980.     sprite_update();
  981.  
  982.     if (palette_recalc())    tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  983.  
  984.  
  985.     osd_clearbitmap(Machine->scrbitmap);
  986.  
  987.     /* Draw the road (lines which have "priority" 0x02) */
  988.     if (layers_ctrl & 16)    wecleman_draw_road(bitmap,0x02);
  989.  
  990.     /* Draw the background */
  991.     if (layers_ctrl & 1)
  992.     {
  993.         tilemap_render(bg_tilemap);
  994.         tilemap_draw(bitmap, bg_tilemap,  0);
  995.     }
  996.  
  997.     /* Draw the foreground */
  998.     if (layers_ctrl & 2)
  999.     {
  1000.         tilemap_render(fg_tilemap);
  1001.         tilemap_draw(bitmap, fg_tilemap,  0);
  1002.     }
  1003.  
  1004.     /* Draw the road (lines which have "priority" 0x04) */
  1005.     if (layers_ctrl & 16)    wecleman_draw_road(bitmap,0x04);
  1006.  
  1007.     /* Draw the sprites */
  1008.     if (layers_ctrl & 8)    sprite_draw(sprite_list,0);
  1009.  
  1010.     /* Draw the text layer */
  1011.     if (layers_ctrl & 4)
  1012.     {
  1013.         tilemap_render(txt_tilemap);
  1014.         tilemap_draw(bitmap, txt_tilemap,  0);
  1015.     }
  1016.  
  1017. }
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026. /***************************************************************************
  1027.                                 Hot Chase
  1028. ***************************************************************************/
  1029.  
  1030. void hotchase_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1031. {
  1032.     int i;
  1033.     int layers_ctrl = 0xFFFF;
  1034.  
  1035.     WECLEMAN_LAMPS
  1036.  
  1037.     WECLEMAN_TVKILL
  1038.  
  1039. #ifdef MAME_DEBUG
  1040.     WECLEMAN_LAYERSCTRL
  1041. #endif
  1042.  
  1043.     K051316_tilemap_update_0();
  1044.     K051316_tilemap_update_1();
  1045.     get_sprite_info();
  1046.  
  1047.     palette_init_used_colors();
  1048.  
  1049.     hotchase_mark_road_colors();
  1050.     mark_sprites_colors();
  1051.     sprite_update();
  1052.  
  1053.     /* set transparent pens for the K051316 */
  1054.     for (i = 0;i < 128;i++)
  1055.     {
  1056.         palette_used_colors[i * 16] = PALETTE_COLOR_TRANSPARENT;
  1057.         palette_used_colors[i * 16] = PALETTE_COLOR_TRANSPARENT;
  1058.         palette_used_colors[i * 16] = PALETTE_COLOR_TRANSPARENT;
  1059.     }
  1060.  
  1061.     if (palette_recalc())
  1062.         tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  1063.  
  1064.     tilemap_render(ALL_TILEMAPS);
  1065.  
  1066.     fillbitmap(bitmap,palette_transparent_pen,&Machine->drv->visible_area);
  1067.  
  1068.     /* Draw the background */
  1069.     if (layers_ctrl & 1)
  1070.         K051316_zoom_draw_0(bitmap,0);
  1071.  
  1072.     /* Draw the road */
  1073.     if (layers_ctrl & 16)
  1074.     {
  1075.         struct rectangle clip = {0, 512-1, 0, 256-1};
  1076.  
  1077.         fillbitmap(temp_bitmap2,palette_transparent_pen,0);
  1078.         hotchase_draw_road(temp_bitmap2,0,&clip);
  1079.  
  1080.         copybitmapzoom(    bitmap, temp_bitmap2,
  1081.                         0, 0,                                        // flip
  1082.                         -(64+32)*4+32, 0,                            // pos
  1083.                         &Machine->drv->visible_area,                // clip
  1084.                         TRANSPARENCY_PEN,palette_transparent_pen,    // transparency
  1085.                         (2<<16),(1<<16)                                // scale: 16.16 fixed
  1086.                         );
  1087.     }
  1088.  
  1089.     /* Draw the sprites */
  1090.     if (layers_ctrl & 8)    sprite_draw(sprite_list,0);
  1091.  
  1092.     /* Draw the foreground (text) */
  1093.     if (layers_ctrl & 4)
  1094.         K051316_zoom_draw_1(bitmap,0);
  1095. }
  1096.